﻿/*********************************************************

    Copyright (c) Microsoft. All rights reserved.
    This code is licensed under the Microsoft Public License.
    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

*********************************************************/
using System;
using System.Data.Services.Client;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using OData.Silverlight;

namespace SL_OData_Explorer.Views
{
    public partial class ODataATOMDisplayWindow : ChildWindow
    {
        public string ATOM { get; set; }
        public ODataEntity Entity { get; set; }
        public ODataServiceContext ServiceContext { get; set; }
        public ODataATOMDisplayWindow(ODataEntity entity, ODataServiceContext serviceContext)
            : this()
        {
            int rowIndex = 0;
            Entity = entity;
            ServiceContext = serviceContext;
            txtEntitySetName.Text = entity.EntityType.Name;
            txtEntityATOM.Text = entity.OData_Atom;
            BuildEntityFields(entity, rowIndex);
            //ATOM = entity.OData_Atom;
            //txtEntityATOM.Text = ATOM;
        }

        private int BuildEntityFields(ODataEntity entity, int rowIndex)
        {
            Thickness margin = new Thickness(2);
            foreach (EntityProperty property in entity.EntityType.Properties)
            {
                RowDefinition newRow = new RowDefinition();
                gdEntityProperties.RowDefinitions.Add(newRow);
                bool IsReadOnly = entity.EntityType.KeyProperties.Contains(property.PropertyName);

                if (!entity.Columns.ContainsKey(property.PropertyName))
                {
                    continue;
                }

                TextBlock propertyStart = new TextBlock() { Text = property.PropertyName, Margin = margin };
                Control propertyValue = null;
                if (property.PropertyType == typeof(string))
                {
                    propertyValue = new TextBox() { Text = entity[property.PropertyName].ToString(), Width = 200, Margin = margin, IsReadOnly = IsReadOnly, Tag = property.PropertyName };
                }
                else if (property.PropertyType == typeof(bool))
                {
                    propertyValue = new CheckBox() { IsChecked = bool.Parse(entity[property.PropertyName].ToString()), Margin = margin, IsEnabled = !IsReadOnly, Tag = property.PropertyName };
                }
                else if (property.PropertyType == typeof(DateTime))
                {
                    propertyValue = new DatePicker() { Text = entity[property.PropertyName].ToString(), Width = 200, Margin = margin, IsEnabled = !IsReadOnly, Tag = property.PropertyName };
                }
                else
                {
                    propertyValue = new TextBox() { Text = entity[property.PropertyName].ToString(), Width = 200, Margin = margin, IsReadOnly = IsReadOnly, Tag = property.PropertyName };
                }
                Grid.SetColumn(propertyStart, 0);
                Grid.SetRow(propertyStart, rowIndex);
                Grid.SetRow(propertyValue, rowIndex++);
                Grid.SetColumn(propertyValue, 1);
                gdEntityProperties.Children.Add(propertyStart);
                gdEntityProperties.Children.Add(propertyValue);
            }
            return rowIndex;
        }

        public ODataATOMDisplayWindow()
        {
            InitializeComponent();
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }

        private void DeleteEntity(object sender, RoutedEventArgs eventArgs)
        {
            UserPrompt confirmDeletePrompt = new UserPrompt("Are you sure you want to delete this entity?");
            confirmDeletePrompt.Show();
            confirmDeletePrompt.Closed += new EventHandler(confirmDeletePrompt_Closed);

        }

        void confirmDeletePrompt_Closed(object sender, EventArgs e)
        {

            UserPrompt confirmDeletePrompt = sender as UserPrompt;
            if (confirmDeletePrompt.DialogResult.HasValue && confirmDeletePrompt.DialogResult.Value)
            {
                scrollViewer.Visibility = System.Windows.Visibility.Collapsed;
                spEntityOperations.Visibility = System.Windows.Visibility.Visible;
                pbSavingChanges.Visibility = System.Windows.Visibility.Visible;

                ServiceContext.DeleteObject(Entity);
                string userMessage = "Succesfully Deleted!";
                int expectedStatusCode = (int)HttpStatusCode.NoContent;
                ExecuteChange(userMessage, expectedStatusCode);
            }
        }

        private void ExecuteChange(string userMessage, int expectedStatusCode)
        {
            ServiceContext.SendingRequest += new EventHandler<System.Data.Services.Client.SendingRequestEventArgs>(ServiceContext_SendingRequest);
            ServiceContext.BeginSaveChanges(
                (asResult) =>
                {
                    Dispatcher.BeginInvoke(
                        () =>
                        {
                            try
                            {
                                DataServiceResponse response = ServiceContext.EndSaveChanges(asResult);
                                foreach (ChangeOperationResponse changeResponse in response.OfType<ChangeOperationResponse>())
                                {
                                    if (changeResponse.StatusCode == expectedStatusCode)
                                    {
                                        txtResponseDetails.Text = userMessage;
                                    }
                                    icResponseHeaders.ItemsSource = changeResponse.Headers;
                                }

                            }
                            catch (DataServiceRequestException saveChangesError)
                            {
                                foreach (ChangeOperationResponse changeOperation in saveChangesError.Response.OfType<ChangeOperationResponse>())
                                {
                                    txtResponseDetails.Text = changeOperation.StatusCode.ToString();
                                    icResponseHeaders.ItemsSource = changeOperation.Headers;
                                }
                            }
                            finally
                            {
                                pbSavingChanges.Visibility = System.Windows.Visibility.Collapsed;
                            }
                        }
                        );

                }, null
                );
        }

        void ServiceContext_SendingRequest(object sender, System.Data.Services.Client.SendingRequestEventArgs e)
        {
            Dispatcher.BeginInvoke(
                () =>
                {
                    icRequestHeaders.ItemsSource = e.RequestHeaders;
                }
                );
        }

        private void SaveChangesToEntity(object sender, RoutedEventArgs eventArgs)
        {
            scrollViewer.Visibility = System.Windows.Visibility.Collapsed;
            spEntityOperations.Visibility = System.Windows.Visibility.Visible;
            pbSavingChanges.Visibility = System.Windows.Visibility.Visible;

            foreach (EntityProperty property in Entity.EntityType.Properties)
            {
                FrameworkElement uiElement = gdEntityProperties.Children.OfType<FrameworkElement>().Where(child => child.Tag == property.PropertyName).FirstOrDefault();
                object value = null;
                if (uiElement is TextBox)
                {
                    value = ((TextBox)uiElement).Text;
                }
                else if (uiElement is DatePicker)
                {
                    value = ((DatePicker)uiElement).Text;
                }
                if (Entity.Columns.ContainsKey(property.PropertyName))
                {
                    Entity[property.PropertyName] = value;
                }
                else
                {
                    Entity.Columns.Add(property.PropertyName, value);
                }
            }
            ServiceContext.UpdateObject(Entity);
            string userMessage = "Succesfully Updated!";
            int expectedStatusCode = (int)HttpStatusCode.NoContent;
            ExecuteChange(userMessage, expectedStatusCode);
        }

        private void btnSendChanges_Click(object sender, RoutedEventArgs e)
        {

        }

        private void Image_ImageFailed(object sender, ExceptionRoutedEventArgs e)
        {

        }
    }
}


